/*
 * Copyright (C) 2004, Velocityme Partnership
 * SearchActions.java
 *
 * Created on 02 October 2004, 07:10
 */

package com.velocityme.www.interfaces;

import com.velocityme.interfaces.*;
import com.velocityme.utility.NodeSearchResult;
import com.velocityme.www.actionforms.AdvancedSearchActionForm;
import com.velocityme.www.actionforms.SearchDateActionForm;
import com.velocityme.www.actionforms.SearchOthersResponsibilityActionForm;
import com.velocityme.www.actionforms.SearchReportActionForm;
import com.velocityme.www.actionforms.SortResultsActionForm;
import com.velocityme.www.dto.SearchReportDTO;
import com.velocityme.www.utility.NodeUtil;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import javax.servlet.http.*;
import javax.swing.tree.TreeModel;
import org.apache.struts.action.*;
import org.apache.struts.actions.DispatchAction;

/**
 *
 * @author  Robert
 */
public class SearchActions extends DispatchAction {
    
    /** Creates a new instance of SearchActions */
    public SearchActions() {
    }
    
    public ActionForward showLastWeekTasks(ActionMapping mapping, 
                                           ActionForm form,
                                           HttpServletRequest request,
                                           HttpServletResponse response) throws Exception {
        NodePK nodePK = (NodePK)request.getAttribute("nodePK");
        SearchDateActionForm searchDateActionForm = new SearchDateActionForm();
        Calendar lastWeek = Calendar.getInstance();
        lastWeek.setTimeInMillis(lastWeek.getTimeInMillis() - 7 * 24 * 60 * 60 * 1000);
        searchDateActionForm.setNodeId(nodePK.getNodeId().intValue());
        searchDateActionForm.setStartDate(lastWeek);
        Calendar today = Calendar.getInstance();
        return showNewTasks(mapping, searchDateActionForm, request, response);
    }
    
    public ActionForward showNewTasks(ActionMapping mapping, 
                                      ActionForm form,
                                      HttpServletRequest request,
                                      HttpServletResponse response) throws Exception {
        SearchDateActionForm searchDateActionForm = (SearchDateActionForm)form;
        NodePK nodePK = new NodePK(new Integer(searchDateActionForm.getNodeId()));
        HttpSession session = request.getSession();
        KeySession key = (KeySession)session.getAttribute("sessionKey");
        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
        Calendar date = searchDateActionForm.getStartDate();
        session.setAttribute("resultValues", cs.findNewTasks(key, nodePK, date.getTime()));
        session.setAttribute("years", NodeUtil.getInstance().getYears());
        session.setAttribute("months", NodeUtil.getInstance().getMonths());
        session.setAttribute("days", NodeUtil.getInstance().getDays());
        session.setAttribute("searchDateActionForm", searchDateActionForm);
        return mapping.findForward("ACTION_DISPLAY_NEW_TASKS");
    }
    
    public ActionForward showCompletedLastWeekTasks(ActionMapping mapping, 
                                           ActionForm form,
                                           HttpServletRequest request,
                                           HttpServletResponse response) throws Exception {
        NodePK nodePK = (NodePK)request.getAttribute("nodePK");
        SearchDateActionForm searchDateActionForm = new SearchDateActionForm();
        Calendar lastWeek = Calendar.getInstance();
        lastWeek.setTimeInMillis(lastWeek.getTimeInMillis() - 7 * 24 * 60 * 60 * 1000);
        searchDateActionForm.setNodeId(nodePK.getNodeId().intValue());
        searchDateActionForm.setStartDate(lastWeek);
        Calendar today = Calendar.getInstance();
        return showCompletedTasks(mapping, searchDateActionForm, request, response);
    }
    
    public ActionForward showCompletedTasks(ActionMapping mapping, 
                                            ActionForm form,
                                            HttpServletRequest request,
                                            HttpServletResponse response) throws Exception {
        SearchDateActionForm searchDateActionForm = (SearchDateActionForm)form;
        NodePK nodePK = new NodePK(new Integer(searchDateActionForm.getNodeId()));
        HttpSession session = request.getSession();
        KeySession key = (KeySession)session.getAttribute("sessionKey");
        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
        Calendar date = searchDateActionForm.getStartDate();
        session.setAttribute("resultValues", cs.findCompletedTasks(key, nodePK, date.getTime()));
        session.setAttribute("years", NodeUtil.getInstance().getYears());
        session.setAttribute("months", NodeUtil.getInstance().getMonths());
        session.setAttribute("days", NodeUtil.getInstance().getDays());
        session.setAttribute("searchDateActionForm", searchDateActionForm);
        return mapping.findForward("ACTION_DISPLAY_COMPLETED_TASKS");
    }
    
    public ActionForward showChangedTodayTasks(ActionMapping mapping, 
                                               ActionForm form,
                                               HttpServletRequest request,
                                               HttpServletResponse response) throws Exception {
        NodePK nodePK = (NodePK)request.getAttribute("nodePK");
        SearchDateActionForm searchDateActionForm = new SearchDateActionForm();
        searchDateActionForm.setNodeId(nodePK.getNodeId().intValue());
        Calendar lastWeek = Calendar.getInstance();
        lastWeek.setTimeInMillis(lastWeek.getTimeInMillis() - 1 * 24 * 60 * 60 * 1000);
        searchDateActionForm.setStartDate(lastWeek);
        Calendar today = Calendar.getInstance();
        searchDateActionForm.setStopDate(today);
        return showChangedTasks(mapping, searchDateActionForm, request, response);
    }
    
    public ActionForward showChangedTasks(ActionMapping mapping, 
                                          ActionForm form,
                                          HttpServletRequest request,
                                          HttpServletResponse response) throws Exception {
        SearchDateActionForm searchDateActionForm = (SearchDateActionForm)form;
        NodePK nodePK = new NodePK(new Integer(searchDateActionForm.getNodeId()));
        HttpSession session = request.getSession();
        KeySession key = (KeySession)session.getAttribute("sessionKey");
        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
        Calendar startDate = searchDateActionForm.getStartDate();
        Calendar stopDate = searchDateActionForm.getStopDate();
        session.setAttribute("resultValues", cs.findChangedTasks(key, nodePK, startDate.getTime(), stopDate.getTime()));
        session.setAttribute("years", NodeUtil.getInstance().getYears());
        session.setAttribute("months", NodeUtil.getInstance().getMonths());
        session.setAttribute("days", NodeUtil.getInstance().getDays());
        session.setAttribute("searchDateActionForm", searchDateActionForm);
        return mapping.findForward("ACTION_DISPLAY_CHANGED_TASKS");
    }
    
    public ActionForward showOthersResponsibleTasksSetup(ActionMapping mapping,
                                                         ActionForm form,
                                                         HttpServletRequest request,
                                                         HttpServletResponse response) throws Exception {
        NodePK nodePK = (NodePK)request.getAttribute("nodePK");
        HttpSession session = request.getSession();
        KeySession key = (KeySession)session.getAttribute("sessionKey");
        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
        session.setAttribute("contactablePairs", NodeUtil.getAllContactablePairs(key, cs));
        // setup default values
        SearchOthersResponsibilityActionForm actionForm = new SearchOthersResponsibilityActionForm();
        actionForm.setNodeId(nodePK.getNodeId());
        session.setAttribute("actionForm", actionForm);
        return mapping.findForward("ACTION_SHOW_OTHERS_RESPONSIBLE_TASKS_SETUP");
    }
    
    public ActionForward showOthersResponsibleTasksSearchReport(ActionMapping mapping,
                                                                ActionForm form,
                                                                HttpServletRequest request,
                                                                HttpServletResponse response) throws Exception {
        SearchOthersResponsibilityActionForm actionForm = (SearchOthersResponsibilityActionForm)form;
        HttpSession session = request.getSession();
        KeySession key = (KeySession)session.getAttribute("sessionKey");
        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
        NodePK nodePK = new NodePK(actionForm.getNodeId());
        if (request.getParameter("btnSubmit").equals("OK")) {
            ContactablePK[] contactablePks = actionForm.getContactablePKs();
            Boolean includeDescendents = actionForm.getIncludeDescendents();
            session.setAttribute("resultValues", cs.findContactablesResponsibleTasks(key, nodePK, contactablePks, includeDescendents.booleanValue()));
            return mapping.findForward("ACTION_OK");
        }
        // Cancel simply displays the original node again
        else {
            request.setAttribute("nodePK", nodePK);
            return mapping.findForward("ACTION_CANCEL");
        }
    }
    
    public ActionForward showAdvancedSearchSetup(ActionMapping mapping, 
                                                 ActionForm form,
                                                 HttpServletRequest request,
                                                 HttpServletResponse response) throws Exception {
        NodePK nodePK = (NodePK)request.getAttribute("nodePK");
        HttpSession session = request.getSession();
        KeySession key = (KeySession)session.getAttribute("sessionKey");
        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
        session.setAttribute("years", NodeUtil.getInstance().getYears());
        session.setAttribute("months", NodeUtil.getInstance().getMonths());
        session.setAttribute("days", NodeUtil.getInstance().getDays());
        session.setAttribute("statusPairs", NodeUtil.getInstance().getAllStatusPairs(key, cs));
        Collection contactablePairs = new ArrayList();
        TreeModel contactableTreeModel = cs.getContactableValueTree(key);
        NodeUtil.recursiveAddContactable(contactableTreeModel, contactableTreeModel.getRoot(), contactablePairs, 0);
        session.setAttribute("contactablePairs", contactablePairs);
        // setup default values
        Calendar now = Calendar.getInstance();
        AdvancedSearchActionForm advancedSearchActionForm = new AdvancedSearchActionForm();
        advancedSearchActionForm.setNodeId(nodePK.getNodeId());
        advancedSearchActionForm.setStartYear(now.get(Calendar.YEAR));
        advancedSearchActionForm.setStartMonth(now.get(Calendar.MONTH));
        advancedSearchActionForm.setStartDay(now.get(Calendar.DATE));
        advancedSearchActionForm.setStopYear(now.get(Calendar.YEAR));
        advancedSearchActionForm.setStopMonth(now.get(Calendar.MONTH));
        advancedSearchActionForm.setStopDay(now.get(Calendar.DATE));
        session.setAttribute("advancedSearchActionForm", advancedSearchActionForm);
        return mapping.findForward("ACTION_DISPLAY_SETUP");
    }
    
    public ActionForward showAdvancedSearchReport(ActionMapping mapping,
                                                  ActionForm form,
                                                  HttpServletRequest request,
                                                  HttpServletResponse response) throws Exception {
        AdvancedSearchActionForm advancedSearchActionForm = (AdvancedSearchActionForm)form;
        HttpSession session = request.getSession();
        KeySession key = (KeySession)session.getAttribute("sessionKey");
        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
        NodePK nodePK = new NodePK(advancedSearchActionForm.getNodeId());
        if (request.getParameter("btnSubmit").equals("OK")) {
            Integer[] ids = advancedSearchActionForm.getIdArray();
            String[] keywords = advancedSearchActionForm.getKeywordsArray();
            Date start = advancedSearchActionForm.getStartDate();
            Date stop = advancedSearchActionForm.getStopDate();
            StatusPK[] statusPks = advancedSearchActionForm.getStatusPKs();
            ContactablePK[] contactablePks = advancedSearchActionForm.getContactablePKs();
            session.setAttribute("resultValues", cs.findParameterSearch(key, nodePK, ids, keywords, start, stop, statusPks, contactablePks));
            return mapping.findForward("ACTION_DISPLAY_ADVANCED_SEARCH_RESULTS");
        }
        // Cancel simply displays the original node again
        else {
            request.setAttribute("nodePK", nodePK);
            return mapping.findForward("ACTION_CANCEL");
        }
    }
    
    public ActionForward showReport(ActionMapping mapping,
                                    ActionForm form,
                                    HttpServletRequest request,
                                    HttpServletResponse response) throws Exception {
        SearchReportActionForm searchReportActionForm = (SearchReportActionForm)form;
        HttpSession session = request.getSession();
        KeySession key = (KeySession)session.getAttribute("sessionKey");
        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
        NodePK nodePK = new NodePK((Integer)session.getAttribute("nodeId"));
        Collection resultsValues = (Collection)session.getAttribute("resultValues");
        Integer taskCount = new Integer(resultsValues.size());
        Collection searchEntries = cs.searchReportValue(key,
                                                        nodePK,
                                                        resultsValues,
                                                        searchReportActionForm.getIncludeStateChanges().booleanValue(),
                                                        searchReportActionForm.getIncludeComments().booleanValue(),
                                                        searchReportActionForm.getIncludeResponsibility().booleanValue());
        SearchReportDTO searchReportDTO = new SearchReportDTO(cs.getNodePathName(key, nodePK),
                                                              new Date(),
                                                              taskCount,
                                                              searchEntries);
        session.setAttribute("searchReportDTO", searchReportDTO);
        return mapping.findForward("ACTION_REPORT_SUCCESS");
    }
    
    private void calcDirection(HttpServletRequest request,
                               String sortColumn) {
        HttpSession session = request.getSession();
        int sortDirection;
        if (sortColumn.equals(session.getAttribute("sortColumn"))) {
            sortDirection = ((Integer)session.getAttribute("sortDirection")).intValue();
	    switch(sortDirection) {
                case -1: sortDirection = 1; break;
                case 1: sortDirection = -1; break;
            }
        }
        else {
            session.setAttribute("sortColumn", sortColumn);
            sortDirection = 1;
        }
        session.setAttribute("sortDirection", new Integer(sortDirection));
    }
    
    private int sortDirection(HttpServletRequest request) {
        return ((Integer)request.getSession().getAttribute("sortDirection")).intValue();
    }
    
    private ActionForward sortResults(ActionMapping mapping,
                                      HttpServletRequest request,
                                      Comparator comparator) {
        HttpSession session = request.getSession();
        List resultValues = new ArrayList((Collection)session.getAttribute("resultValues"));
        Collections.sort(resultValues, comparator);
        session.setAttribute("resultValues", resultValues);
        return mapping.findForward("ACTION_OK");
    }
    
    public ActionForward sortId(ActionMapping mapping,
                                ActionForm form,
                                final HttpServletRequest request,
                                HttpServletResponse response) throws Exception {
        calcDirection(request, "id");
        return sortResults(mapping, request, new Comparator() {
            public int compare(Object o1, Object o2) {
                return ((NodeSearchResult)o1).getId().compareTo(((NodeSearchResult)o2).getId()) * sortDirection(request);
            }
        });
    }
    
    public ActionForward sortPriority(ActionMapping mapping,
                                      ActionForm form,
                                      final HttpServletRequest request,
                                      HttpServletResponse response) throws Exception {
        calcDirection(request, "priority");
        return sortResults(mapping, request, new Comparator() {
            public int compare(Object o1, Object o2) {
                return ((NodeSearchResult)o1).getPriority().compareTo(((NodeSearchResult)o2).getPriority()) * sortDirection(request);
            }
        });
    }
    
    public ActionForward sortPercent(ActionMapping mapping,
                                     ActionForm form,
                                     final HttpServletRequest request,
                                     HttpServletResponse response) throws Exception {
        calcDirection(request, "percent");
        return sortResults(mapping, request, new Comparator() {
            public int compare(Object o1, Object o2) {
                return ((NodeSearchResult)o1).getPercent().compareTo(((NodeSearchResult)o2).getPercent()) * sortDirection(request);
            }
        });
    }
    
    public ActionForward sortName(ActionMapping mapping,
                                  ActionForm form,
                                  final HttpServletRequest request,
                                  HttpServletResponse response) throws Exception {
        calcDirection(request, "name");
        return sortResults(mapping, request, new Comparator() {
            public int compare(Object o1, Object o2) {
                return ((NodeSearchResult)o1).getName().compareTo(((NodeSearchResult)o2).getName()) * sortDirection(request);
            }
        });
    }
    
    public ActionForward sortType(ActionMapping mapping,
                                  ActionForm form,
                                  final HttpServletRequest request,
                                  HttpServletResponse response) throws Exception {
        calcDirection(request, "taskType");
        return sortResults(mapping, request, new Comparator() {
            public int compare(Object o1, Object o2) {
                return ((NodeSearchResult)o1).getTaskType().compareTo(((NodeSearchResult)o2).getTaskType()) * sortDirection(request);
            }
        });
    }
    
    public ActionForward sortStatus(ActionMapping mapping,
                                    ActionForm form,
                                    final HttpServletRequest request,
                                    HttpServletResponse response) throws Exception {
        calcDirection(request, "status");
        return sortResults(mapping, request, new Comparator() {
            public int compare(Object o1, Object o2) {
                return ((NodeSearchResult)o1).getStatus().compareTo(((NodeSearchResult)o2).getStatus()) * sortDirection(request);
            }
        });
    }
    
    public ActionForward sortResponsible(ActionMapping mapping,
                                         ActionForm form,
                                         final HttpServletRequest request,
                                         HttpServletResponse response) throws Exception {
        calcDirection(request, "responsible");
        return sortResults(mapping, request, new Comparator() {
            public int compare(Object o1, Object o2) {
                return ((NodeSearchResult)o1).getResponsible().compareTo(((NodeSearchResult)o2).getResponsible()) * sortDirection(request);
            }
        });
    }
    
}
